package org.ddd.book.infrastructure.book;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ddd.book.domain.base.repository.IAddressRepository;
import org.ddd.book.domain.base.vo.AddressVO;
import org.ddd.book.domain.book.entity.LibraryEntity;
import org.ddd.book.domain.book.repository.ILibraryRepository;
import org.ddd.book.domain.book.vo.LibraryBaseInfoVO;
import org.ddd.book.domain.factoty.RepositoryFactory;
import org.ddd.book.domain.security.service.ISecurityService;
import org.ddd.book.domain.security.vo.UserVO;
import org.ddd.book.infrastructure.book.dao.LibraryMapperService;
import org.ddd.book.infrastructure.book.po.LibraryPO;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

@Repository
@AllArgsConstructor
@Slf4j
public class LibraryRepositoryMysqlImpl implements ILibraryRepository {

    private final LibraryMapperService libraryMapperService;
    private final ISecurityService securityService;

    private LibraryEntity po2entity(LibraryPO po) {
        LibraryEntity entity = new LibraryEntity();
        BeanUtil.copyProperties(po, entity);
        entity.setBaseInfo(LibraryBaseInfoVO.builder().introductory(po.getIntroductory()).openTime(po.getOpenTime()).build());
        entity.setAdmin(new UserVO(po.getAdminUserId(), po.getAdminUserName(), null));
        // AddressVO，这里就不封装了，使用延时加载
        return entity;
    }

    @Override
    public LibraryEntity get(Serializable id) {
        LibraryPO libraryPO = libraryMapperService.getById(id);
        if (null == libraryPO) {
            return null;
        }
        return po2entity(libraryPO);
    }

    @Override
    public void save(LibraryEntity entity) {
        LibraryPO libraryPO = new LibraryPO();
        BeanUtil.copyProperties(entity, libraryPO);
        BeanUtil.copyProperties(entity.getBaseInfo(), libraryPO);
        UserVO currentUser = securityService.currentUser();
        if (null == entity.getId()) {
            libraryPO.setCreateBy(currentUser.getUserId());
            libraryPO.setCreateTime(LocalDateTime.now());
        }
        libraryPO.setUpdateBy(currentUser.getUserId());
        libraryPO.setUpdateTime(LocalDateTime.now());
        if (null != entity.getAdmin()) {
            libraryPO.setAdminUserId(entity.getAdmin().getUserId());
            libraryPO.setAdminUserName(entity.getAdmin().getUserName());
        }
        if (null != entity.getAddress()) {
            libraryPO.setCountryCode(entity.getAddress().getCountry().getCountryCode());
            libraryPO.setProvinceCode(entity.getAddress().getProvince().getProvinceCode());
            libraryPO.setCityCode(entity.getAddress().getCity().getCityCode());
            libraryPO.setAddressDetail(entity.getAddress().getDetail());
            libraryPO.setFullAddressDetail(entity.getAddress().getCountry().getCountryName() + entity.getAddress().getProvince().getProvinceName() + entity.getAddress().getCity().getCityName() + entity.getAddress().getDetail());
        }
        libraryMapperService.saveOrUpdate(libraryPO);
    }

    @Override
    public LibraryEntity findByLibraryName(String libraryName) {
        List<LibraryPO> libraryPOList = libraryMapperService.lambdaQuery().eq(LibraryPO::getLibraryName, libraryName).list();
        if (CollectionUtil.isEmpty(libraryPOList)) {
            return null;
        }
        LibraryEntity library = new LibraryEntity();
        BeanUtil.copyProperties(libraryPOList.get(0), library);
        return library;
    }

    @Override
    public void remove(Serializable id) {
        // 移除图书馆实体
        libraryMapperService.removeById(id);
    }

    @Override
    public AddressVO findAddress(Long libraryId) {
        LibraryPO libraryPO = libraryMapperService.getById(libraryId);
        if (null == libraryPO) {
            return null;
        }
        return RepositoryFactory.get(IAddressRepository.class).get(libraryPO.getCountryCode(), libraryPO.getProvinceCode(), libraryPO.getCityCode(), libraryPO.getAddressDetail());
    }

    @Override
    public List<LibraryEntity> allLibrary() {
        List<LibraryPO> libraryPOList = libraryMapperService.list();
        if (CollectionUtil.isEmpty(libraryPOList)) {
            return Collections.emptyList();
        }
        List<LibraryEntity> entityList = new LinkedList<>();
        libraryPOList.forEach(po -> entityList.add(po2entity(po)));
        return entityList;
    }

}
